import React, { useState, useRef, useEffect, useCallback, memo } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import { Stage, Layer, Rect, Transformer } from 'react-konva';
import styles from './PdfViewer.module.css';

// 设置 pdf.js worker
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`;

// 使用 memo 优化页面渲染
const PageComponent = memo(({ pageNum, scale, rotation, onLoadSuccess, annotations, newAnnotation, 
  selectedTool, onMouseDown, onMouseMove, onMouseUp, onClick, onStageClick, selectedAnnotation,
  selectedAnnotationId, transformerRef, onTransformEnd, onDragEnd }) => {
  const [pageSize, setPageSize] = useState({ width: 0, height: 0 });
  const [isPageLoaded, setIsPageLoaded] = useState(false);

  const handlePageLoadSuccess = useCallback((page) => {
    const viewport = page.getViewport({ scale, rotation });
    setPageSize({
      width: viewport.width,
      height: viewport.height
    });
    setIsPageLoaded(true);
    onLoadSuccess && onLoadSuccess(page);
  }, [scale, rotation, onLoadSuccess]);

  // 添加 useEffect 来处理选中的标注
  useEffect(() => {
    if (selectedAnnotationId && transformerRef.current && isPageLoaded) {
      // 找到选中的标注节点
      const stage = transformerRef.current.getStage();
      if (!stage) return;
      
      const selectedNode = stage.findOne(`#${selectedAnnotationId}`);
      
      // 将变换控件附加到选中的标注上
      if (selectedNode) {
        transformerRef.current.nodes([selectedNode]);
        transformerRef.current.getLayer().batchDraw();
      }
    } else if (transformerRef.current) {
      // 如果没有选中的标注，清除变换控件
      transformerRef.current.nodes([]);
      transformerRef.current.getLayer().batchDraw();
    }
  }, [selectedAnnotationId, isPageLoaded]);

  return (
    <div className={styles.pageWrapper}>
      <Page
        pageNumber={pageNum}
        scale={scale}
        rotate={rotation}
        onLoadSuccess={handlePageLoadSuccess}
        className={styles.page}
        renderTextLayer={false}
        renderAnnotationLayer={false}
        loading={<div>加载页面中...</div>}
        error={<div>加载页面出错</div>}
      />
      {isPageLoaded && pageSize.width > 0 && (
        <Stage
          width={pageSize.width}
          height={pageSize.height}
          onMouseDown={(e) => {
            e.evt.preventDefault();
            onMouseDown && onMouseDown(e, pageNum);
          }}
          onMouseMove={(e) => {
            e.evt.preventDefault();
            onMouseMove && onMouseMove(e);
          }}
          onMouseUp={(e) => {
            e.evt.preventDefault();
            onMouseUp && onMouseUp(e);
          }}
          onClick={(e) => {
            e.evt.preventDefault();
            // 检查是否点击在舞台空白处
            if (e.target === e.target.getStage()) {
              onStageClick && onStageClick(e);
            } else {
              onClick && onClick(e, pageNum);
            }
          }}
          className={styles.annotationLayer}
        >
          <Layer>
            {(annotations[pageNum] || []).map((annotation) => (
              <Rect
                key={annotation.id}
                id={annotation.id}
                {...annotation}
                onClick={(e) => onClick(e, pageNum)}
                onTap={(e) => onClick(e, pageNum)}
                draggable={selectedTool === 'mouse'}
                onDragEnd={(e) => onDragEnd(e, pageNum)}
                onTransformEnd={(e) => onTransformEnd(e, pageNum)}
                stroke={annotation.id === selectedAnnotationId ? '#00ff00' : annotation.stroke}
                strokeWidth={annotation.id === selectedAnnotationId ? 3 : annotation.strokeWidth}
                fill={annotation.id === selectedAnnotationId ? 'rgba(0, 255, 0, 0.1)' : 'transparent'}
              />
            ))}
            {newAnnotation && newAnnotation.pageNum === pageNum && (
              <Rect
                {...newAnnotation}
                fill="transparent"
              />
            )}
            <Transformer
              ref={transformerRef}
              boundBoxFunc={(oldBox, newBox) => {
                // 限制最小尺寸
                const minSize = 5;
                if (newBox.width < minSize || newBox.height < minSize) {
                  return oldBox;
                }
                return newBox;
              }}
              keepRatio={false}  // 允许自由调整宽高比
              enabledAnchors={['top-left', 'top-right', 'bottom-left', 'bottom-right']}  // 只显示四个角的控制点
              anchorFill="#00ff00"  // 控制点的填充颜色
              anchorStroke="#00ff00"  // 控制点的边框颜色
              anchorSize={8}  // 控制点的大小
              borderStroke="#00ff00"  // 变换框的边框颜色
              borderDash={[2, 2]}  // 虚线边框
            />
          </Layer>
        </Stage>
      )}
    </div>
  );
});

const PdfViewer = ({ file, selectedTool, onAnnotationChange }) => {
  const [numPages, setNumPages] = useState(null);
  const [currentScreen, setCurrentScreen] = useState(1);
  const [scale, setScale] = useState(1.0);
  const [rotation, setRotation] = useState(0);
  const [annotations, setAnnotations] = useState({});
  const [isDrawing, setIsDrawing] = useState(false);
  const [newAnnotation, setNewAnnotation] = useState(null);
  const [selectedAnnotation, setSelectedAnnotation] = useState(null);
  const [selectedAnnotationId, setSelectedAnnotationId] = useState(null);
  const transformerRef = useRef(null);
  const pdfContainerRef = useRef(null);
  const viewerRef = useRef(null);
  const observerRef = useRef(null);

  const PAGES_PER_SCREEN = 4;

  const onDocumentLoadSuccess = useCallback(({ numPages }) => {
    setNumPages(numPages);
  }, []);

  const onPageLoadSuccess = useCallback((page) => {
    // 页面加载成功的处理
  }, []);

  const handleZoomIn = useCallback(() => {
    setScale(prevScale => Math.min(prevScale + 0.2, 3));
  }, []);

  const handleZoomOut = useCallback(() => {
    setScale(prevScale => Math.max(prevScale - 0.2, 0.5));
  }, []);

  const handleRotate = useCallback(() => {
    setRotation(prev => (prev + 90) % 360);
  }, []);

  const handlePrevScreen = useCallback(() => {
    setCurrentScreen(prev => Math.max(prev - 1, 1));
  }, []);

  const handleNextScreen = useCallback(() => {
    setCurrentScreen(prev => Math.min(prev + 1, Math.ceil(numPages / PAGES_PER_SCREEN)));
  }, [numPages]);

  const handleMouseDown = useCallback((e, pageNum) => {
    if (selectedTool !== 'rectangle') return;
    
    const stage = e.target.getStage();
    const point = stage.getPointerPosition();
    setIsDrawing(true);
    setNewAnnotation({
      x: point.x,
      y: point.y,
      width: 0,
      height: 0,
      id: Date.now().toString(),
      stroke: 'red',
      strokeWidth: 2,
      pageNum
    });
  }, [selectedTool]);

  const handleMouseMove = useCallback((e) => {
    if (!isDrawing || selectedTool !== 'rectangle') return;

    const stage = e.target.getStage();
    const point = stage.getPointerPosition();
    
    setNewAnnotation(prev => ({
      ...prev,
      width: point.x - prev.x,
      height: point.y - prev.y
    }));
  }, [isDrawing, selectedTool]);

  const handleMouseUp = useCallback(() => {
    if (!isDrawing) return;
    
    if (newAnnotation && (Math.abs(newAnnotation.width) > 5 || Math.abs(newAnnotation.height) > 5)) {
      const annotation = {
        ...newAnnotation,
        width: Math.abs(newAnnotation.width),
        height: Math.abs(newAnnotation.height),
        x: newAnnotation.width < 0 ? newAnnotation.x + newAnnotation.width : newAnnotation.x,
        y: newAnnotation.height < 0 ? newAnnotation.y + newAnnotation.height : newAnnotation.y
      };
      
      setAnnotations(prev => {
        const newAnnotations = {
          ...prev,
          [annotation.pageNum]: [...(prev[annotation.pageNum] || []), annotation]
        };
        onAnnotationChange && onAnnotationChange(newAnnotations);
        return newAnnotations;
      });
    }
    
    setIsDrawing(false);
    setNewAnnotation(null);
  }, [isDrawing, newAnnotation, onAnnotationChange]);

  const handleAnnotationClick = useCallback((e, pageNum) => {
    if (selectedTool === 'eraser') {
      const clickedAnnotationId = e.target.attrs.id;
      setAnnotations(prev => {
        const newAnnotations = {
          ...prev,
          [pageNum]: (prev[pageNum] || []).filter(ann => ann.id !== clickedAnnotationId)
        };
        onAnnotationChange && onAnnotationChange(newAnnotations);
        return newAnnotations;
      });
      return;
    }

    const clickedAnnotation = e.target;
    setSelectedAnnotation(clickedAnnotation);
    setSelectedAnnotationId(clickedAnnotation.attrs.id);
  }, [selectedTool, onAnnotationChange]);

  const handleStageClick = useCallback((e) => {
    if (e.target === e.target.getStage()) {
      setSelectedAnnotation(null);
      setSelectedAnnotationId(null);
    }
  }, []);

  const handleTransformEnd = useCallback((e, pageNum) => {
    const node = e.target;
    const scaleX = node.scaleX();
    const scaleY = node.scaleY();

    node.scaleX(1);
    node.scaleY(1);

    setAnnotations(prev => {
      const newAnnotations = {
        ...prev,
        [pageNum]: (prev[pageNum] || []).map(ann => {
          if (ann.id === node.attrs.id) {
            return {
              ...ann,
              x: node.x(),
              y: node.y(),
              width: node.width() * scaleX,
              height: node.height() * scaleY,
            };
          }
          return ann;
        })
      };
      onAnnotationChange && onAnnotationChange(newAnnotations);
      return newAnnotations;
    });
  }, [onAnnotationChange]);

  const handleAnnotationDragEnd = useCallback((e, pageNum) => {
    const node = e.target;
    setAnnotations(prev => {
      const newAnnotations = {
        ...prev,
        [pageNum]: (prev[pageNum] || []).map(ann => {
          if (ann.id === node.attrs.id) {
            return {
              ...ann,
              x: node.x(),
              y: node.y(),
            };
          }
          return ann;
        })
      };
      onAnnotationChange && onAnnotationChange(newAnnotations);
      return newAnnotations;
    });
  }, [onAnnotationChange]);

  // 处理容器滚动事件
  useEffect(() => {
    const container = pdfContainerRef.current;
    if (!container) return;

    const handleWheel = (e) => {
      if (e.ctrlKey) {
        // 如果按住Ctrl键，则进行缩放
        e.preventDefault();
        if (e.deltaY < 0) {
          handleZoomIn();
        } else {
          handleZoomOut();
        }
      } else {
        // 正常滚动
        e.stopPropagation();
      }
    };

    container.addEventListener('wheel', handleWheel, { passive: false });
    return () => container.removeEventListener('wheel', handleWheel);
  }, [handleZoomIn, handleZoomOut]);

  // 设置 Intersection Observer 来优化页面渲染
  useEffect(() => {
    if (typeof window !== 'undefined' && window.IntersectionObserver) {
      observerRef.current = new IntersectionObserver(
        (entries) => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              const pageWrapper = entry.target;
              pageWrapper.style.opacity = '1';
              pageWrapper.style.transform = 'translateY(0)';
            }
          });
        },
        {
          root: pdfContainerRef.current,
          threshold: 0.1,
          rootMargin: '100px'
        }
      );

      // 观察所有页面包装器
      const pageWrappers = document.querySelectorAll(`.${styles.pageWrapper}`);
      pageWrappers.forEach(wrapper => {
        wrapper.style.opacity = '0';
        wrapper.style.transform = 'translateY(20px)';
        wrapper.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
        observerRef.current.observe(wrapper);
      });
    }

    return () => {
      if (observerRef.current) {
        observerRef.current.disconnect();
      }
    };
  }, [numPages]);

  const renderPage = useCallback((pageNum) => {
    const startPage = (currentScreen - 1) * PAGES_PER_SCREEN + 1;
    const endPage = Math.min(startPage + PAGES_PER_SCREEN - 1, numPages);
    
    if (pageNum < startPage || pageNum > endPage) return null;

    return (
      <PageComponent
        key={pageNum}
        pageNum={pageNum}
        scale={scale}
        rotation={rotation}
        onLoadSuccess={onPageLoadSuccess}
        annotations={annotations}
        newAnnotation={newAnnotation}
        selectedTool={selectedTool}
        onMouseDown={handleMouseDown}
        onMouseMove={handleMouseMove}
        onMouseUp={handleMouseUp}
        onClick={handleAnnotationClick}
        onStageClick={handleStageClick}
        selectedAnnotation={selectedAnnotation}
        selectedAnnotationId={selectedAnnotationId}
        transformerRef={transformerRef}
        onTransformEnd={handleTransformEnd}
        onDragEnd={handleAnnotationDragEnd}
      />
    );
  }, [currentScreen, numPages, scale, rotation, annotations, newAnnotation, selectedTool, 
    handleMouseDown, handleMouseMove, handleMouseUp, handleAnnotationClick, handleStageClick,
    selectedAnnotation, selectedAnnotationId, handleTransformEnd, handleAnnotationDragEnd, onPageLoadSuccess]);

  return (
    <div 
      className={styles.pdfViewer} 
      data-testid="pdf-viewer"
      data-tool={selectedTool}
      data-zoom={scale}
      data-rotation={rotation}
      data-page={currentScreen}
      ref={viewerRef}
    >
      <div className={styles.toolbar}>
        <div className={styles.pageControls}>
          <button
            className={styles.toolButton}
            onClick={handlePrevScreen}
            disabled={currentScreen <= 1}
            title="上一页"
          >
            上一屏
          </button>
          <span className={styles.pageInfo}>
            第 {(currentScreen - 1) * PAGES_PER_SCREEN + 1} - {Math.min(currentScreen * PAGES_PER_SCREEN, numPages)} 页 / 共 {numPages} 页
          </span>
          <button
            className={styles.toolButton}
            onClick={handleNextScreen}
            disabled={currentScreen >= Math.ceil(numPages / PAGES_PER_SCREEN)}
            title="下一页"
          >
            下一屏
          </button>
        </div>
        <div className={styles.zoomControls}>
          <button
            className={styles.toolButton}
            onClick={handleZoomOut}
            title="缩小"
          >
            缩小
          </button>
          <span className={styles.zoomInfo}>{Math.round(scale * 100)}%</span>
          <button
            className={styles.toolButton}
            onClick={handleZoomIn}
            title="放大"
          >
            放大
          </button>
          <button
            className={styles.toolButton}
            onClick={handleRotate}
            title="旋转"
          >
            旋转
          </button>
        </div>
      </div>
      <div className={styles.pdfContainer} ref={pdfContainerRef}>
        <Document
          file={file}
          onLoadSuccess={onDocumentLoadSuccess}
          className={styles.document}
          loading={<div>加载中...</div>}
          error={<div>加载PDF文件时出错</div>}
          noData={<div>请选择PDF文件</div>}
        >
          {numPages && 
            Array.from(new Array(numPages), (_, index) => renderPage(index + 1))}
        </Document>
      </div>
    </div>
  );
};

export default memo(PdfViewer); 